package learn.sec;

import cn.hutool.core.lang.Console;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;

/**
 * Created By  醉美柳舞之众星捧月
 *
 * @author 宋贤坤
 * @date 2019/6/6 18:31
 */
public class SecTest {

    private static final String IV = "WELOy1iDdxKX7xwsvtO2FQ==";
    private static final String SEC = "ltNwq7RkQUiT+yPK1L4GlA==";
    private static final String DATA = "lt6Q1qbDAxFDwgU7cV1N7aJUCyAzKVhi5cP9aPotnXsIK7JpG4O8E7qghM1n8AGmL8PLS1R0CXm2OZoBE6py8ZtXLM+ZfjBJpYOU9/NIZc2PRdh+GnJcGEgVAWf2q4fy2dgLuwbzF/rwzH/8cWHtaM/hn9jnEXiGGLZ068gqG0jrwco6mjmxLXMf7O6E/kdJ+zXiBduX7thC5KvEW99nWgJt434lbXNEMa0bKE/zNpN03A18XWuQK9Ofy7EBg+2T4FCq7rxSaYBZAYNKObUwKBzr+dovJf09tJOx5tkBXTzQDS+12BWEOCLsvpeEZ47AyNG5n6BNhbcBfQ1oOF1oiUyM8uzzW61GMstztxgC3YQOAF4WybWRTQnEtikzv56brV2BmLx88E1Fk+W8dsydRSnSlMBiPWh406SqPqDeK5Pdw29/vebnkuPL0OxWEO6f6jHp0WmQgz/Wj2c84+WcADoyiSMkyIHNxQd+6a7ntGE=";

    public static void main(String[] args) throws Exception {

        String master = AesUtils.master(IV, DATA, SEC);
        Console.error(master);

        String slave = AesUtils.slave(IV, DATA, SEC);
        Console.error(slave);

        String s = AesUtils.decryptPhone(IV, DATA, SEC);
        System.out.println(s);

    }
}

class AesUtils {

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public static String master(String iv, String date, String sessionKeys) {

        byte[] keyByte = Base64.decodeBase64(sessionKeys);
        byte[] ivByte = Base64.decodeBase64(iv);
        byte[] dataByte = Base64.decodeBase64(date);

        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, "UTF-8");
                return result;
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String slave(String iv, String date, String sessionKeys) throws Exception {

        byte[] keyByte = Base64.decodeBase64(sessionKeys);
        byte[] ivByte = Base64.decodeBase64(iv);
        byte[] dataByte = Base64.decodeBase64(date);

        AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivByte);
        byte[] data;
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            data = cipher.doFinal(dataByte);
        } catch (Exception e) {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            data = cipher.doFinal(dataByte);
        }
        String result = new String(data, "UTF-8");
        return result;
    }

    public static String decryptPhone(String iv, String date, String sessionKeys) throws Exception {

        byte[] keyByte = Base64.decodeBase64(sessionKeys);
        byte[] ivByte = Base64.decodeBase64(iv);
        byte[] dataByte = Base64.decodeBase64(date);

        AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivByte);
        byte[] data;
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            data = cipher.doFinal(dataByte);
        } catch (Exception e) {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            data = cipher.doFinal(dataByte);
        }
        String result = new String(data, "UTF-8");
        return result;
    }
}
